﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using ProjScan.Config.GUIConfig;
using ProjScan.ScanRule.CustomRules;
using ProjScan.Tools;
using System.Reflection;
using UnityEngine;

namespace ProjScan.Config
{
    //
    // 摘要:
    //     自定义规则检测配置信息
    internal class CustomRulesCheckConfig : BaseConfig
    {
        public List<Type> ruleTypes;

        public Dictionary<ushort, ICustomRule> ruleTypeDictionary;

        public Dictionary<string, RuleInfo> dicRuleInfo;

        public override void Init()
        {
            hasSeparateTargetDirSettings = false;
            hasfailedData = false;
            hasWhiteList = false;
            hasFixRule = false;
            if (dicRuleConfig == null)
            {
                dicRuleConfig = new Dictionary<string, RuleConfig>();
            }
            else
            {
                dicRuleConfig.Clear();
            }
        }

        //
        // 摘要:
        //     通过程序集找到定义好的自定义规则，用来生成规则字典
        //
        // 异常:
        //   T:ProjScan.ScanRule.CustomRules.ColumnRuleIDConflictEx:
        //     规则id冲突
        private void LoadCustomRules()
        {
            ruleTypes = new List<Type>();
            ruleTypeDictionary = new Dictionary<ushort, ICustomRule>();
            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (Assembly assembly in assemblies)
            {
                try
                {
                    Type[] types = assembly.GetTypes();
                    for (int j = 0; j < types.Length; j++)
                    {
                        if (types[j] != typeof(ICustomRule) && typeof(ICustomRule).IsAssignableFrom(types[j]))
                        {
                            ruleTypes.Add(types[j]);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ScanLog.Instance.LogInfo(ScanLog.LogLevel.EXCEPTION, ProjScan.Modules.Module.Custom_Rules_Check, ScanLog.Stage.s1, "Ctor", ex.GetType()?.ToString() + "\n" + ex.Message + "\n" + ex.StackTrace);
                }
            }

            for (int k = 0; k < ruleTypes.Count; k++)
            {
                ICustomRule customRule = Activator.CreateInstance(ruleTypes[k]) as ICustomRule;
                try
                {
                    ruleTypeDictionary.Add(customRule.Id, customRule);
                }
                catch (ArgumentException message)
                {
                    Debug.Log(message);
                    throw new ColumnRuleIDConflictEx();
                }
            }
        }

        private string GetRuleKey(ICustomRule customRuleInstance)
        {
            return $"CustomRule.{customRuleInstance.Id}";
        }

        //
        // 摘要:
        //     设置规则信息查询字典
        private void SetupCustomRulesInfo()
        {
            dicRuleInfo = new Dictionary<string, RuleInfo>();
            foreach (KeyValuePair<ushort, ICustomRule> item in ruleTypeDictionary)
            {
                ICustomRule value = item.Value;
                string ruleKey = GetRuleKey(value);
                RuleInfo value2 = default(RuleInfo);
                value2.ruleName = value.Description;
                value2.Description = value.Guidelines;
                dicRuleInfo.Add(ruleKey, value2);
            }
        }

        private void ResolveCustomRule()
        {
            JObject jObject = (JObject)_rootConfig["Rule_List"];
            foreach (KeyValuePair<ushort, ICustomRule> item in ruleTypeDictionary)
            {
                ICustomRule value = item.Value;
                RuleConfig value2 = default(RuleConfig);
                value2.ruleKey = GetRuleKey(value);
                JObject jObject2 = jObject?[value2.ruleKey] as JObject;
                value2.checkEnabled = (jObject2 == null || !object.Equals(jObject2["checkEnabled"], (JValue)(JToken)false));
                value2.fixEnabled = false;
                value2.hasSrcPath = true;
                dicRuleConfig.Add(value2.ruleKey, value2);
            }
        }

        public override void LoadConfig(JObject data)
        {
            _rootConfig = (((JObject)data["Custom_Rules_Check"]) ?? new JObject());
            LoadCustomRules();
            SetupCustomRulesInfo();
            ResolveCustomRule();
        }

        protected override JObject SaveJObjectRule()
        {
            JObject jObject = new JObject();
            JObject jObject2 = new JObject();
            jObject.Add("Rule_List", jObject2);
            foreach (KeyValuePair<string, RuleConfig> item in dicRuleConfig)
            {
                RuleConfig value = item.Value;
                JObject jObject3 = new JObject();
                jObject3.Add("checkEnabled", (JToken)value.checkEnabled);
                jObject2.Add(value.ruleKey, jObject3);
            }

            return jObject;
        }

        public override void SaveConfig(JObject data)
        {
            data.Add("Custom_Rules_Check", SaveJObjectRule());
        }
    }
}